home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GameStar 2004 April
/
Gamestar_61_2004-04_dvdb.iso
/
DVDStar
/
Editace
/
hltp.exe
/
{app}
/
Applications
/
QuArK
/
quarkpy
/
mdlhandles.py
< prev
next >
Wrap
Text File
|
2004-01-05
|
14KB
|
447 lines
""" QuArK - Quake Army Knife
Model editor mouse handles.
"""
#
# Copyright (C) 1996-99 Armin Rigo
# THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
# FOUND IN FILE "COPYING.TXT"
#
#$Header: /cvsroot/quark/runtime/quarkpy/mdlhandles.py,v 1.8 2001/03/15 21:07:49 aiv Exp $
#
# See comments in maphandles.py.
#
import quarkx
import math
from qdictionnary import Strings
import qhandles
from mdlutils import *
import mdlentities
import qmenu
vertexdotcolor = 0
#
# The handle classes.
#
class CenterHandle(qhandles.CenterHandle):
"Like qhandles.CenterHandle, but specifically for the Model editor."
def menu(self, editor, view):
return mdlentities.CallManager("menu", self.centerof, editor) + self.OriginItems(editor, view)
class IconHandle(qhandles.IconHandle):
"Like qhandles.IconHandle, but specifically for the Model editor."
def menu(self, editor, view):
return mdlentities.CallManager("menu", self.centerof, editor) + self.OriginItems(editor, view)
class MdlEyeDirection(qhandles.EyeDirection):
MODE = SS_MODEL
class VertexHandle(qhandles.GenericHandle):
"Frame Vertex handle."
size = (3,3)
def __init__(self, pos):
qhandles.GenericHandle.__init__(self, pos)
self.cursor = CR_CROSSH
def menu(self, editor, view):
def forcegrid1click(m, self=self, editor=editor, view=view):
self.Action(editor, self.pos, self.pos, MB_CTRL, view, Strings[560])
def addhere1click(m, self=self, editor=editor, view=view):
addvertex(editor.Root.currentcomponent, self.pos)
def removevertex1click(m, self=self, editor=editor, view=view):
removevertex(editor.Root.currentcomponent, self.index)
def pick_vertex(m, self=self, editor=editor, view=view):
if self.index not in editor.picked:
editor.picked = editor.picked + [ self.index ]
else:
editor.picked.remove(self.index)
return [qmenu.item("&Add Vertex Here", addhere1click, "add vertex to component"),
qmenu.item("&Remove Vertex", removevertex1click, "removes a vertex from the component"),
qmenu.item("&Pick Vertex", pick_vertex, "picks a vertex for creating triangles"),
qmenu.sep,
qmenu.item("&Force to grid", forcegrid1click,"force vertex to grid")] + self.OriginItems(editor, view)
def draw(self, view, cv, draghandle=None):
p = view.proj(self.pos)
if p.visible:
cv.setpixel(p.x, p.y, vertexdotcolor)
editor = mapeditor()
if editor is not None:
if self.index in editor.picked:
cv.pencolor = WHITE
cv.rectangle(p.x-3, p.y-3, p.x+3, p.y+3)
def drag(self, v1, v2, flags, view):
p0 = view.proj(self.pos)
if not p0.visible: return
if flags&MB_CTRL:
v2 = qhandles.aligntogrid(v2, 0)
delta = v2-v1
editor = mapeditor()
if editor is not None:
if editor.lock_x==1:
delta = quarkx.vect(0, delta.y, delta.z)
if editor.lock_y==1:
delta = quarkx.vect(delta.x, 0, delta.z)
if editor.lock_z==1:
delta = quarkx.vect(delta.x, delta.y, 0)
self.draghint = vtohint(delta)
new = self.frame.copy()
if delta or (flags&MB_REDIMAGE):
vtxs = new.vertices
vtxs[self.index] = vtxs[self.index] + delta
new.vertices = vtxs
return [self.frame], [new]
class SkinHandle(qhandles.GenericHandle):
"Skin Handle for s / t positioning"
size = (3,3)
def __init__(self, pos, tri_index, ver_index, comp):
qhandles.GenericHandle.__init__(self, pos)
self.cursor = CR_CROSSH
self.tri_index = tri_index
self.ver_index = ver_index
self.component = comp
# def drag(self, v1, v2, flags, view):
# p0 = view.proj(self.pos)
# if not p0.visible: return
# if flags&MB_CTRL:
# v2 = qhandles.aligntogrid(v2, 0)
# delta = v2-v1
# editor = mapeditor()
# if editor is not None:
# if editor.lock_x==1:
# delta = quarkx.vect(0, delta.y, 0)
# if editor.lock_y==1:
# delta = quarkx.vect(delta.x, 0, 0)
# self.draghint = "moving s/t vertex: " + ftoss(delta.x) + ", " + ftoss(delta.y)
# new = self.component.copy()
# if delta or (flags&MB_REDIMAGE):
# tris = new.triangles
#
# oldtri = tris[self.tri_index]
# oldvert = oldtri[self.ver_index]
# newvert = [oldvert[0], oldvert[1]+delta.x, oldvert[2]+delta.y]
# if (self.ver_index == 0):
# newtri = [newvert, oldtri[1], oldtri[2]]
# elif (self.ver_index == 1):
# newtri = [oldtri[0], newvert, oldtri[2]]
# elif (self.ver_index == 2):
# newtri = [oldtri[0], oldtri[1], newvert]
# tris[self.tri_index] = newtri
#
# new.triangles = tris
# return [self.component], [new]
def draw(self, view, cv, draghandle=None):
p = view.proj(self.pos)
if p.visible:
cv.setpixel(p.x, p.y, vertexdotcolor)
class BoneHandle(qhandles.GenericHandle):
"Bone Handle"
size = (3,3)
def __init__(self, pos):
qhandles.GenericHandle.__init__(self, pos)
self.cursor = CR_CROSSH
def drag(self, v1, v2, flags, view):
p0 = view.proj(self.pos)
if not p0.visible: return
if flags&MB_CTRL:
v2 = qhandles.aligntogrid(v2, 0)
delta = v2-v1
editor = mapeditor()
if editor is not None:
if editor.lock_x==1:
delta = quarkx.vect(0, delta.y, delta.z)
if editor.lock_y==1:
delta = quarkx.vect(delta.x, 0, delta.z)
if editor.lock_z==1:
delta = quarkx.vect(delta.x, delta.y, 0)
self.draghint = vtohint(delta)
new = self.bone.copy()
if delta or (flags&MB_REDIMAGE):
if (self.s_or_e == 0):
apoint = self.bone.start_point
apoint = apoint + delta
new.start_point = apoint
else:
apoint = self.bone.end_point
debug(str(self.bone.bone_length))
if self.bone["length_locked"]=="1":
apoint = ProjectKeepingLength(
self.bone.start_point,
self.bone.end_point + delta,
self.bone.bone_length
)
else:
apoint = apoint + delta
new.end_offset = apoint - self.bone.start_point
return [self.bone], [new]
def draw(self, view, cv, draghandle=None):
p = view.proj(self.pos)
if p is None:
return
if p.visible:
cv.brushcolor = WHITE
cv.ellipse(p.x - 3, p.y - 3, p.x + 3, p.y + 3)
def skinzoom(view, center=None):
if center is None:
center = view.screencenter
view.setprojmode("2D", view.info["matrix"]*view.info["scale"], 0)
bmin, bmax = view.info["bbox"]
x1=y1=x2=y2=None
for x in (bmin.x,bmax.x): # all 8 corners of the bounding box
for y in (bmin.y,bmax.y):
for z in (bmin.z,bmax.z):
p = view.proj(x,y,z)
if (x1 is None) or (p.x<x1): x1=p.x
if (y1 is None) or (p.y<y1): y1=p.y
if (x2 is None) or (p.x>x2): x2=p.x
if (y2 is None) or (p.y>y2): y2=p.y
view.setrange(x2-x1+36, y2-y1+34, 0.5*(bmin+bmax))
# trick : if we are far enough and scroll bars are hidden,
# the code below clamb the position of "center" so that
# the picture is completely inside the view.
x1=y1=x2=y2=None
for x in (bmin.x,bmax.x): # all 8 corners of the bounding box
for y in (bmin.y,bmax.y):
for z in (bmin.z,bmax.z):
p = view.proj(x,y,z) # re-proj... because of setrange
if (x1 is None) or (p.x<x1): x1=p.x
if (y1 is None) or (p.y<y1): y1=p.y
if (x2 is None) or (p.x>x2): x2=p.x
if (y2 is None) or (p.y>y2): y2=p.y
w,h = view.clientarea
w,h = (w-36)/2, (h-34)/2
x,y,z = view.proj(center).tuple
t1,t2 = x2-w,x1+w
if t2>=t1:
if x<t1: x=t1
elif x>t2: x=t2
t1,t2 = y2-h,y1+h
if t2>=t1:
if y<t1: y=t1
elif y>t2: y=t2
view.screencenter = view.space(x,y,z)
p = view.proj(view.info["origin"])
view.depth = (p.z-0.1, p.z+100.0)
def buildskinvertices(editor, view, component):
"builds a list of handles to display on the skinview"
def drawsingleskin(view, component=component, editor=editor):
view.color = BLACK
view.drawmap(component.skindrawobject)
# view.solidimage(component.currentskin)
view.drawmap(component.skindrawobject, DM_REDRAWFACES|DM_OTHERCOLOR, 0x2584C9) # draw the face contour
editor.finishdrawing(view)
# end of drawsingleskin
h = [ ]
tris = component.triangles
for i in range(len(tris)):
tri = tris[i]
for j in range(len(tri)):
vtx = tri[j]
h.append(SkinHandle(quarkx.vect(vtx[1], vtx[2], 0), i, j, component))
# n = quarkx.vect(1,1,1)
# v = orthogonalvect(n, view)
org = component.originst
view.handles = qhandles.FilterHandles(h, SS_MODEL)
view.flags = view.flags &~ (MV_HSCROLLBAR | MV_VSCROLLBAR)
view.viewmode = "tex"
view.info = {"type": "2D",
"matrix": matrix_rot_z(pi2),
"origin": org,
"scale": 1,
"custom": skinzoom,
"bbox": quarkx.boundingboxof(map(lambda h: h.pos, view.handles)),
"noclick": None,
"mousemode": None
}
skinzoom(view, org)
view.flags = view.flags | qhandles.vfSkinView;
editor.setupview(view, drawsingleskin, 0)
#
# Functions to build common lists of handles.
#
def BuildCommonHandles(editor, ex):
"Build a list of handles to display on all map views."
fs = ex.uniquesel
if (fs is None) or editor.linearbox:
return []
else:
#
# Get the list of handles from the entity manager.
#
return mdlentities.CallManager("handlesopt", fs, editor)
def BuildHandles(editor, ex, view):
"Build a list of handles to display on one map view."
fs = ex.uniquesel
if (fs is None) or editor.linearbox:
#
# Display a linear mapping box.
#
list = ex.sellist
box = quarkx.boundingboxof(list)
if box is None:
h = []
else:
manager = qhandles.LinHandlesManager(MapColor("Linear"), box, list)
h = manager.BuildHandles(editor.interestingpoint())
h = qhandles.FilterHandles(h, SS_MODEL)
else:
#
# Get the list of handles from the entity manager.
#
h = mdlentities.CallManager("handles", fs, editor, view)
#
# The 3D view "eyes".
#
for v in editor.layout.views:
if (v is not view) and (v.info["type"] == "3D"):
h.append(qhandles.EyePosition(view, v))
h.append(MdlEyeDirection(view, v))
return qhandles.FilterHandles(h, SS_MODEL)
#
# Drag Objects
#
class RectSelDragObject(qhandles.RectangleDragObject):
"A red rectangle that selects the polyhedrons it touches."
def rectanglesel(self, editor, x,y, rectangle):
if not ("T" in self.todo):
editor.layout.explorer.uniquesel = None
polylist = editor.Root.findallsubitems("", ":p")
lastsel = None
for p in polylist:
if rectangle.intersects(p):
p.selected = 1
lastsel = p
if lastsel is not None:
editor.layout.explorer.focus = lastsel
editor.layout.explorer.selchanged()
#
# Mouse Clicking and Dragging on map views.
#
def MouseDragging(self, view, x, y, s, handle):
"Mouse Drag on a Model View."
#
# qhandles.MouseDragging builds the DragObject.
#
if handle is not None:
s = handle.click(self)
if s and ("S" in s):
self.layout.actionmpp() # update the multi-pages-panel
return qhandles.MouseDragging(self, view, x, y, s, handle, MapColor("GrayImage", SS_MODEL))
def MouseClicked(self, view, x, y, s, handle):
"Mouse Click on a Model view."
#
# qhandles.MouseClicked manages the click but doesn't actually select anything
#
flags = qhandles.MouseClicked(self, view, x, y, s, handle)
if "1" in flags:
#
# This mouse click must select something.
#
self.layout.setupdepth(view)
choice = view.clicktarget(self.Root, x, y)
# this is the list of frame triangles we clicked on
if len(choice):
choice.sort() # list of (clickpoint,component,triangleindex) tuples - sort by depth
clickpoint, obj, tridx = choice[0]
if (obj.type != ':mc') or (type(tridx) is not type(0)): # should not occur
return flags
if ("M" in s) and obj.selected: # if Menu, we try to keep the currently selected objects
return flags
# if "T" in s: # if Multiple selection request
# obj.togglesel()
# if obj.selected:
# self.layout.explorer.focus = obj
# self.layout.explorer.selchanged()
# else:
# ...
# self.layout.explorer.uniquesel = obj
else:
if not ("T" in s): # clear current selection
self.layout.explorer.uniquesel = None
return flags+"S"
return flags
# ----------- REVISION HISTORY ------------
#
#
#$Log: mdlhandles.py,v $
#Revision 1.8 2001/03/15 21:07:49 aiv
#fixed bugs found by fpbrowser
#
#Revision 1.7 2001/02/07 18:40:47 aiv
#bezier texture vertice page started.
#
#Revision 1.6 2001/02/05 20:03:12 aiv
#Fixed stupid bug when displaying texture vertices
#
#Revision 1.5 2000/10/11 19:07:47 aiv
#Bones, and some kinda skin vertice viewer
#
#Revision 1.4 2000/08/21 21:33:04 aiv
#Misc. Changes / bugfixes
#
#Revision 1.2 2000/06/02 16:00:22 alexander
#added cvs headers
#
#
#